﻿using System.IO.IsolatedStorage;
using System.IO;

namespace nRoute.Samples.Sudoku.Components
{
    /// <remarks>
    /// Ideas from http://www.willasrari.com/blog/json-serialization-with-silverlight-isolated-storage-for-the-win/000322.aspx
    /// </remarks>
    public static class IsolatedStore
    {
        // Serializable Data Files

        public static void SaveDataObject<T>(T value, string fileName)
        {
            try
            {
                using (var _store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    var _objectXml = Serializer.Serialize<T>(value);
                    using (var _stream = new IsolatedStorageFileStream(fileName, FileMode.Create, _store))
                    {
                        using (var _writer = new StreamWriter(_stream))
                            _writer.Write(_objectXml);
                    }
                }
            }
            catch (IsolatedStorageException)
            {
            }
        }

        public static T LoadDataObject<T>(string fileName)
        {
            try
            {
                using (var _store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (!_store.FileExists(fileName)) 
                        return default(T);

                    using (var _fileStream = new IsolatedStorageFileStream(fileName, FileMode.Open, _store))
                    {
                        using (var _reader = new StreamReader(_fileStream)) 
                            return Serializer.Deserialize<T>(_reader.ReadToEnd());
                    }
                }

            }
            catch (IsolatedStorageException)
            {
                return default(T);
            }
        }

        // Text Files

        public static void SaveText(string text, string fileName)
        {
            try
            {
                using (var _store = IsolatedStorageFile.GetUserStoreForApplication())
                {

                    using (var _stream = new IsolatedStorageFileStream(fileName, FileMode.Create, _store))
                    {
                        using (var _writer = new StreamWriter(_stream)) 
                            _writer.Write(text);
                    }
                }
            }
            catch (IsolatedStorageException)
            {
            }
        }

        public static string LoadText(string fileName)
        {
            try
            {
                using (var _store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (!_store.FileExists(fileName)) return string.Empty;

                    using (var _fileStream = new IsolatedStorageFileStream(fileName, FileMode.Open, _store))
                    {
                        using (var _reader = new StreamReader(_fileStream)) 
                            return _reader.ReadToEnd();
                    }
                }
            }
            catch (IsolatedStorageException)
            {
                return string.Empty;
            }
        }

        // Binary Files

        public static void SaveBinary(byte[] buffer, string fileName)
        {
            try
            {
                using (var _store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (var _stream = new IsolatedStorageFileStream(fileName, FileMode.Create, _store))
                    {
                        using (var _writer = new BinaryWriter(_stream)) 
                            _writer.Write(buffer);
                    }
                }
            }
            catch (IsolatedStorageException)
            {
            }
        }

        public static byte[] LoadBinary(string fileName)
        {
            try
            {

                using (var _store = IsolatedStorageFile.GetUserStoreForApplication())
                {

                    if (!_store.FileExists(fileName)) return null;

                    using (var _fileStream = new IsolatedStorageFileStream(fileName, FileMode.Open, _store))
                    using (var _reader = new BinaryReader(_fileStream))
                    {

                        // we read it into the a memory stream
                        using (var _output = new MemoryStream())
                        {

                            // Create a buffer to transfer the data
                            byte[] _buffer = new byte[1024];
                            int _bytesRead = 0;
                            long _totalBytes = 0;

                            // we read all the bytes
                            while ((_bytesRead = _reader.Read(_buffer, 0, _buffer.Length)) > 0)
                            {

                                _totalBytes += _bytesRead;
                                _output.Write(_buffer, 0, _bytesRead);

                            }

                            return _output.ToArray();

                        }

                    }

                }

            }
            catch (IsolatedStorageException)
            {
                return null;
            }
        }

        // Files Related

        public static bool FileExists(string fileName)
        {
            try
            {
                return IsolatedStorageFile.GetUserStoreForApplication().FileExists(fileName);
            }
            catch (IsolatedStorageException)
            {
                return false;
            }
        }

        public static void DeleteFile(string fileName)
        {
            try
            {
                IsolatedStorageFile.GetUserStoreForApplication().DeleteFile(fileName);
            }
            catch (IsolatedStorageException)
            {
            }
        }

        // Settings Related

        public static void SaveSetting<T>(T value, string key)
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
            {
                IsolatedStorageSettings.ApplicationSettings[key] = value;
            }
            else
            {
                IsolatedStorageSettings.ApplicationSettings.Add(key, value);
            }

            // we save this
            IsolatedStorageSettings.ApplicationSettings.Save();
        }

        public static T LoadSetting<T>(string key)
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(key))
            {
                return (T)IsolatedStorageSettings.ApplicationSettings[key];
            }
            else
            {
                return default(T);
            }
        }

        public static bool SettingExists(string key)
        {
            return IsolatedStorageSettings.ApplicationSettings.Contains(key);
        }

        public static void DeleteSetting(string key)
        {
            IsolatedStorageSettings.ApplicationSettings.Remove(key);
            IsolatedStorageSettings.ApplicationSettings.Save();
        }
    }
}
